using System.IdentityModel.Tokens.Jwt;
using System.Text;
using Microsoft.IdentityModel.Tokens;

namespace MallApi.Middlewares;

/// <summary>
/// JWT认证中间件
/// </summary>
public class JwtMiddleware
{
  private readonly RequestDelegate _next;
  private readonly IConfiguration _configuration;

  public JwtMiddleware(RequestDelegate next, IConfiguration configuration)
  {
    _next = next;
    _configuration = configuration;
  }

  public async Task Invoke(HttpContext context)
  {
    var token = context.Request.Headers["Authorization"].FirstOrDefault()?.Split(" ").Last();

    if (token != null)
      AttachUserToContext(context, token);

    await _next(context);
  }

  private void AttachUserToContext(HttpContext context, string token)
  {
    try
    {
      var tokenHandler = new JwtSecurityTokenHandler();
      // 注意：在实际应用中，这个密钥应该存储在配置文件中
      var key = Encoding.ASCII.GetBytes(_configuration["Jwt:Key"] ?? "your-secret-key");

      tokenHandler.ValidateToken(token, new TokenValidationParameters
      {
        ValidateIssuerSigningKey = true,
        IssuerSigningKey = new SymmetricSecurityKey(key),
        ValidateIssuer = false,
        ValidateAudience = false,
        ClockSkew = TimeSpan.Zero
      }, out SecurityToken validatedToken);

      var jwtToken = (JwtSecurityToken)validatedToken;
      var userId = jwtToken.Claims.First(x => x.Type == "id").Value;

      // 将用户ID附加到上下文中
      context.Items["UserId"] = userId;
    }
    catch
    {
      // 如果token验证失败，不做任何处理，继续执行下一个中间件
    }
  }
}